package com.bubbles.workspace.sync.entity.source.metadata;


import com.bubbles.engine.data.core.entity.BaseEntity;
import com.bubbles.workspace.sync.constant.Constant;
import com.bubbles.workspace.sync.enums.ConnectType;
import com.bubbles.workspace.sync.enums.DatabaseType;
import com.bubbles.workspace.sync.key.source.metadata.SourceJdbcKey;
import com.bubbles.workspace.sync.properties.SshProperties;
import com.bubbles.workspace.sync.util.SshManager;
import jakarta.persistence.*;
import lombok.*;
import lombok.experimental.Accessors;
import org.hibernate.annotations.Comment;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>description: 源数据源-JDBC </p>
 *
 * @author CryptoNeedle
 * @date 2025-06-19
 */
@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true, exclude = {"sourceServer", "sourceCatalogs"})
@ToString(callSuper = true, exclude = {"sourceServer", "sourceCatalogs"})
@Entity
@EntityListeners(AuditingEntityListener.class)
@Table(schema = "sync", name = "source_jdbc")
@IdClass(SourceJdbcKey.class)
@Comment("源数据源-JDBC")
public class SourceJdbc extends BaseEntity {
    
    @Id
    @Comment("服务器-主机")
    private String host;
    
    @Id
    @Comment("服务器-端口")
    private Integer port;
    
    @Id
    @Enumerated(EnumType.STRING)
    @Comment("JDBC-数据库类型")
    private DatabaseType databaseType;
    
    @Id
    @Comment("JDBC-路径")
    private String route;
    
    @Id
    @Comment("JDBC-用户名称")
    private String userName;
    
    @Comment("JDBC-密码")
    private String password;
    
    @Enumerated(EnumType.STRING)
    @Comment("JDBC-连接类型")
    private ConnectType connectType;
    
    @Comment("JDBC-驱动类")
    private String driverClass;
    
    @Comment("JDBC-连接地址")
    private String url;
    
    @Comment("JDBC-可连接")
    private Boolean connected;
    
    @Comment("JDBC-最后可连接时间")
    private Date connectedDatetime;
    
    @Column(length = 4000)
    @Comment("JDBC-数据库版本")
    private String databaseVersion;
    
    /**
     * 关联关系
     */
    
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumns({@JoinColumn(name = "host", referencedColumnName = "host", insertable = false, updatable = false), @JoinColumn(name = "port", referencedColumnName = "port", insertable = false, updatable = false)})
    private SourceServer sourceServer;
    
    @OneToMany(mappedBy = "sourceJdbc", cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
    private List<SourceCatalog> sourceCatalogs = new ArrayList<>();
    
    /**
     * 其他
     */
    
    public SourceJdbcKey getKey() {
        return new SourceJdbcKey().setHost(this.host)
                                  .setPort(this.port)
                                  .setDatabaseType(this.databaseType)
                                  .setRoute(this.route)
                                  .setUserName(this.userName);
    }
    
    public String getStringKey() {
        return getKey().toString();
    }
    
    public String getInetAddress() {
        return host + ":" + port;
    }
    
    public String getDataSourceUrl(SshProperties sshProperties, SshManager sshManager) {
        if (sshProperties.getEnabled()) {
            Integer proxyPort = sshManager.getProxyPort(this.host, this.port);
            return this.databaseType.getDatabase()
                                    .getJdbcUrl(this.connectType, Constant.LOCAL_HOST, proxyPort, this.route);
        }
        
        return this.url;
    }
}
